import { useEffect, useState, useCallback, useRef } from 'react';
import { ScrollArea } from '../../ui/scroll-area';
import BackButton from '../../ui/BackButton';
import ProviderGrid from './ProviderGrid';
import { useConfig } from '../../ConfigContext';
import { ProviderDetails, setConfigProvider } from '../../../api';
import { toastService } from '../../../toasts';

interface ProviderSettingsProps {
  onClose: () => void;
  isOnboarding: boolean;
  onProviderLaunched?: () => void;
}

export default function ProviderSettings({
  onClose,
  isOnboarding,
  onProviderLaunched,
}: ProviderSettingsProps) {
  const { getProviders } = useConfig();
  const [loading, setLoading] = useState(true);
  const [providers, setProviders] = useState<ProviderDetails[]>([]);
  const initialLoadDone = useRef(false);

  // Create a function to load providers that can be called multiple times
  const loadProviders = useCallback(async () => {
    setLoading(true);
    try {
      // Only force refresh when explicitly requested, not on initial load
      const result = await getProviders(!initialLoadDone.current);
      if (result) {
        setProviders(result);
        initialLoadDone.current = true;
      }
    } catch (error) {
      console.error('Failed to load providers:', error);
    } finally {
      setLoading(false);
    }
  }, [getProviders]);

  // Load providers only once when component mounts
  useEffect(() => {
    loadProviders();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // Intentionally not including loadProviders in deps to prevent reloading

  // This function will be passed to ProviderGrid for manual refreshes after config changes
  const refreshProviders = useCallback(() => {
    if (initialLoadDone.current) {
      getProviders(true).then((result) => {
        if (result) setProviders(result);
      });
    }
  }, [getProviders]);

  // Handler for when a provider is launched if this component is used as part of onboarding page
  const handleProviderLaunch = useCallback(
    async (provider: ProviderDetails) => {
      const provider_name = provider.name;
      const model = provider.metadata.default_model;

      try {
        await setConfigProvider({
          body: {
            provider: provider_name,
            model,
          },
          throwOnError: true,
        });

        toastService.configure({ silent: false });
        toastService.success({
          title: 'Success!',
          msg: `Started goose with ${model} by ${provider.metadata.display_name}. You can change the model via the dropdown.`,
        });

        if (onProviderLaunched) {
          onProviderLaunched();
        } else {
          onClose();
        }
      } catch (error) {
        console.error(`Failed to initialize with provider ${provider_name}:`, error);

        // Show error toast
        toastService.configure({ silent: false });
        toastService.error({
          title: 'Initialization Failed',
          msg: `Failed to initialize with ${provider.metadata.display_name}: ${error instanceof Error ? error.message : String(error)}`,
          traceback: error instanceof Error ? error.stack || '' : '',
        });
      }
    },
    [onClose, onProviderLaunched]
  );

  return (
    <div className="h-screen w-full flex flex-col bg-background-default text-text-default">
      <ScrollArea className="flex-1 w-full">
        <div className="w-full max-w-6xl mx-auto px-4 sm:px-6 md:px-8 pt-12 pb-4">
          {/* Consistent header pattern with back button */}
          <div className="flex flex-col pb-8 border-b border-border-default">
            <div className="flex items-center pt-2 mb-1 no-drag">
              <BackButton onClick={onClose} />
            </div>
            <h1 className="text-4xl font-light mb-4 pt-6" data-testid="provider-selection-heading">
              {isOnboarding ? 'Other providers' : 'Provider Configuration Settings'}
            </h1>
            {isOnboarding && (
              <p className="text-sm sm:text-base text-text-muted max-w-full sm:max-w-2xl">
                Select an AI model provider to get started with goose. You'll need to use API keys
                generated by each provider which will be encrypted and stored locally. You can
                change your provider at any time in settings.
              </p>
            )}
          </div>
        </div>

        <div className="py-8 pt-[20px]">
          {/* Content Area */}
          <div className="w-full max-w-6xl mx-auto pt-4 px-4 sm:px-6 md:px-8">
            <div className="relative z-10">
              {loading ? (
                <div>Loading providers...</div>
              ) : (
                <ProviderGrid
                  providers={providers}
                  isOnboarding={isOnboarding}
                  onProviderLaunch={handleProviderLaunch}
                  refreshProviders={refreshProviders}
                />
              )}
            </div>
          </div>
        </div>
      </ScrollArea>
    </div>
  );
}
